#ifndef _MYEXCEPTION_H_
#define _MYEXCEPTION_H_

#include <stdint.h>
#include <cstdio>
#include <exception>
#include <signal.h>
#include <stdlib.h>

namespace evcrawler
{

    class MyException : public std::exception
    {
        private:
            static const u_int32_t LongMaxStringSize  = 1024;
            static const u_int32_t ShortMaxStringSize = 64;
            static const u_int32_t StringSafePostfix = 4;

        private:
            //information
            uint32_t m_line;
            //append some zeroes at end to prevent the hale Chinese character thing
            char m_filename[ShortMaxStringSize + StringSafePostfix];
            char m_message [LongMaxStringSize  + StringSafePostfix];
            char m_method  [ShortMaxStringSize + StringSafePostfix];

        private:
            static void * operator new(size_t);
            MyException();

        public:
            MyException(const char * message, const char * filename, uint32_t line, const char * method);
            //As there are no handler menbers, it would be save to use the one generated by compiler by default
            //MyException(const MyException &);

            inline const char * Message(void) const
            { return this->m_message; }

            inline const char * FileName(void) const
            { return this->m_filename; }

            inline u_int32_t Line(void) const
            { return this->m_line; }

            inline const char * Method(void) const
            { return this->m_method; }
    };
}

#define MyToolThrow(message) \
    do \
    { \
        throw MyException(message, __FILE__, __LINE__, __func__); \
    } \
    while(false)

#define MyThrowAssert(expression) \
    do \
    { \
        if(expression) \
        { \
        } \
        else \
        { \
            FATAL ("MyThrowAssert Failed. ["#expression"] EMSG[%m]");\
            throw MyException("MyThrowAssert Failed. ["#expression"]", __FILE__, __LINE__, __func__); \
        } \
    } \
    while(false)

#define MySuicideAssert(expression) \
    do \
    { \
        if(expression) \
        { \
        } \
        else \
        { \
            FATAL("MySuicideAssert Failed. ["#expression"] EMSG[%m]"); \
            while(0 != raise(SIGKILL)){} \
            exit(1); \
        } \
    } \
    while(false)

#endif

